package com.security.demo.dao;

import java.util.Collection;
import java.util.List;
import java.util.UUID;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.security.demo.util.Constants;
import com.security.demo.util.ReflectionUtils;


public abstract class BaseJdbcDao<M> {

    @Autowired
    protected JdbcTemplate jdbcTemplate;
    @Autowired
    protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    protected Class<M> entityClass;

    public BaseJdbcDao() {
        this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
    }
    
    public String getId() {
    	return UUID.randomUUID().toString().replaceAll("-", "");
    }


    public M findModel(String sql, Object... args) {
        List<M> list = findModels(sql, args);
        if (CollectionUtils.isEmpty(list)) return null;
        return list.get(0);
    }

    public List<M> findModels(String sql, Object... args) {
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<M>(entityClass), args);
    }

    public boolean saveModel(String sql, M m) {
        int r = namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(m));
        return r > 0;
    }

    public List<M> findModelInParams(String sql, Collection<Object> args) {
        MapSqlParameterSource parameters = new MapSqlParameterSource();
        parameters.addValue(Constants.INPARAMS, args);
        return namedParameterJdbcTemplate.query(sql, parameters,
                new BeanPropertyRowMapper<M>(entityClass));
    }

    public int findCount(String sql, Object... args) {
        return jdbcTemplate.queryForObject(sql, int.class, args);
    }

    public List<String> findStrings(String sql, Object... args) {
        return jdbcTemplate.queryForList(sql, String.class, args);
    }

}
